﻿using BCCommon.TMS.Order;
using BCCommon.TMS.Transport;
using BCDto.TMS.Order.Order;
using BCEntity.TMS.OrderFreightRecord;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;

namespace BCService.TMS.Order.Order
{
    /// <summary>
    /// 转换订单运费信息
    /// </summary>
    public class TransformOrderShippingCostService
    {
        /// <summary>
        /// 获取订单运费计算模型
        /// </summary>
        /// <typeparam name="T">订单基本模型</typeparam>
        /// <param name="dto">订单基本模型信息</param>
        /// <param name="suiteBusinessType">套餐业务类型</param>
        /// <param name="suiteId">套餐Id</param>
        /// <returns></returns>
        public OrderShippingCostRequestDto GetRequestDto<T>(T dto, VehicleSuiteBusinessType? suiteBusinessType, int? suiteId) where T : OrderBaseRequestDto
        {
            if (dto.GoodsAddress.Any(p => !p.GoodsWeight.HasValue && !p.GoodsVolume.HasValue))
            {
                throw new ArgumentException("货物重量及货物体积不能同时为空!");
            }

            if (dto.VehicleTransportBusinessType != TransportBusinessType.RunErrands && dto.VehicleTransportBusinessType != TransportBusinessType.SmallPieces)
            {
                if (!dto.VehicleCategoryReferenceId.HasValue)
                {
                    throw new ArgumentException("请选择车辆分类!");
                }
            }
            if (dto.VehicleTransportBusinessType != TransportBusinessType.SmallPieces && !dto.VehicleTypeId.HasValue)
            {
                throw new ArgumentException("请选择车型!");
            }

            List<OrderShippingCostAddressRequestDto> addressRequestDtos = new List<OrderShippingCostAddressRequestDto>();

            foreach (var item in dto.GoodsAddress.Where(p => p.AddressType == AddressType.Place).OrderBy(p => p.EndIndex))
            {
                OrderShippingCostAddressRequestDto addressDto = new OrderShippingCostAddressRequestDto();
                addressDto.EndCountyCode = item.EndCountyCode;
                addressDto.EndLatitude = item.EndLatitude;
                addressDto.EndLongitude = item.EndLongitude;
                if (addressDto.GoodsWeight.HasValue)
                {
                    addressDto.GoodsWeight = item.GoodsWeight;
                }
                if (addressDto.GoodsVolume.HasValue)
                {
                    addressDto.GoodsVolume = item.GoodsVolume.HasValue ? item.GoodsVolume : item.GoodsLength * item.GoodsWidth * item.GoodsHeight;
                }
                addressRequestDtos.Add(addressDto);
            }

            OrderShippingCostRequestDto shippingCostRequestDto = new OrderShippingCostRequestDto();
            shippingCostRequestDto.Address = dto.ShippingAddress;
            shippingCostRequestDto.ConsigneeAddress = addressRequestDtos;
            shippingCostRequestDto.CountyCode = dto.CountyCode;
            shippingCostRequestDto.VehicleCategoryReferenceId = dto.VehicleCategoryReferenceId;
            shippingCostRequestDto.TransportBusinessType = dto.VehicleTransportBusinessType;
            shippingCostRequestDto.VehicleTypeId = dto.VehicleTypeId;
            shippingCostRequestDto.VehicleCategoryReferenceId = dto.VehicleCategoryReferenceId;
            shippingCostRequestDto.SourceType = dto.SourceType;
            shippingCostRequestDto.FreightType = dto.FreightType;
            var takeGoodsList = dto.GoodsAddress.Where(p => p.AddressType == AddressType.Take);
            if (!takeGoodsList.Any())
            {
                throw new ArgumentException("装货地货物信息不允许为空!");
            }
            if (dto.SourceType != OrderSourceType.TMS)
            {
                List<OrderShippingCostGoodsRequestDto> goodsCheckList = new List<OrderShippingCostGoodsRequestDto>();
                foreach (var item in dto.GoodsChecklist)
                {
                    OrderShippingCostGoodsRequestDto goodsRequestDto = item.As<OrderShippingCostGoodsRequestDto>();
                    goodsCheckList.Add(goodsRequestDto);
                    shippingCostRequestDto.GoodsWeight += item.GoodsWeight;
                    shippingCostRequestDto.GoodsVolume += item.GoodsVolume;
                    shippingCostRequestDto.GoodsNumber += item.GoodsCount;
                    shippingCostRequestDto.GoodsLength = item.GoodsLength;
                    shippingCostRequestDto.GoodsWidth = item.GoodsWidth;
                    shippingCostRequestDto.GoodsHeight = item.GoodsHeight;
                }
                shippingCostRequestDto.GoodsChecklist = goodsCheckList;
            }
            else
            {
                var item = takeGoodsList.First();
                shippingCostRequestDto.GoodsWeight = item.GoodsWeight;
                shippingCostRequestDto.GoodsVolume = item.GoodsVolume;
                shippingCostRequestDto.GoodsLength = item.GoodsLength;
                shippingCostRequestDto.GoodsWidth = item.GoodsWidth;
                shippingCostRequestDto.GoodsHeight = item.GoodsHeight;
                shippingCostRequestDto.GoodsNumber = takeGoodsList.Count();
            }
            if (dto.VehicleTransportBusinessType == TransportBusinessType.Moving)
            {
                shippingCostRequestDto.SuiteBusinessType = suiteBusinessType.Value;
                if (suiteBusinessType == VehicleSuiteBusinessType.EasyMove)
                {
                    shippingCostRequestDto.EasyMoveSuiteConfigId = suiteId;
                }
                else
                {
                    shippingCostRequestDto.WorryFreeMoveSuiteConfigId = suiteId;
                }
            }
            shippingCostRequestDto.IsBook = dto.IsBook;
            shippingCostRequestDto.BookTime = dto.BookTime;
            shippingCostRequestDto.Latitude = dto.Latitude;
            shippingCostRequestDto.Longitude = dto.Longitude;
            return shippingCostRequestDto;
        }

        #region 获取订单运费清单记录列表
        /// <summary>
        /// 获取订单运费清单记录列表
        /// </summary>
        /// <param name="shippingCostList">运费清单</param>
        /// <returns></returns>
        public List<OrderFreightRecordEntity> GetOrderFreightRecords(List<OrderCostChecklistDto> shippingCostList)
        {
            List<OrderFreightRecordEntity> list = new List<OrderFreightRecordEntity>();
            foreach (var item in shippingCostList)
            {
                OrderFreightRecordEntity entity = item.As<OrderFreightRecordEntity>();
                list.Add(entity);
                if (item.Checklist != null && item.Checklist.Any())
                {
                    AddCostChecklistToFreightRecords(item.Checklist, ref list);
                }
            }
            return list;
        }
        private void AddCostChecklistToFreightRecords(List<OrderCostChecklistDto> shippingCostList, ref List<OrderFreightRecordEntity> list)
        {
            foreach (var item in shippingCostList)
            {
                OrderFreightRecordEntity entity = item.As<OrderFreightRecordEntity>();
                list.Add(entity);
                if (item.Checklist != null && item.Checklist.Any())
                {
                    AddCostChecklistToFreightRecords(item.Checklist, ref list);
                }
            }
        }
        #endregion

        #region 还原订单运费费用清单到费用清单
        /// <summary>
        /// 还原订单运费费用清单到费用清单
        /// </summary>
        /// <returns></returns>
        public List<OrderCostChecklistDto> GetOrderCostChecklistByOrderFreightRecord(IEnumerable<OrderFreightRecordEntity> list)
        {
            List<OrderCostChecklistDto> result = new List<OrderCostChecklistDto>();

            foreach(var item in list.Where(p => string.IsNullOrWhiteSpace(p.ParentCostCode)))
            {
                OrderCostChecklistDto dto = item.As<OrderCostChecklistDto>();
                var checklist = list.Where(p => p.ParentCostCode == item.CostCode).As<List<OrderCostChecklistDto>>();
                AddFreightRecordsToCostChecklist(list,ref checklist);
                dto.Checklist = checklist;
                result.Add(dto);
            }
            return result;
        }
        private void AddFreightRecordsToCostChecklist(IEnumerable<OrderFreightRecordEntity> list, ref List<OrderCostChecklistDto> orderCostChecklist)
        {
            foreach (var item in orderCostChecklist)
            {
                var checklist = list.Where(p => p.ParentCostCode == item.CostCode).As<List<OrderCostChecklistDto>>();
                AddFreightRecordsToCostChecklist(list, ref checklist);
                item.Checklist = checklist;
            }
        }
        #endregion

    }
}
